

#ifndef __COMM_COMB_MAP_H__
#define __COMM_COMB_MAP_H__

#include "comm/comm_base.h"
#include "comm/comm_geometry.h"
#include "comm/comm_file.h"
#include "comm/comm_map.h"
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <list>
#include <vector>

using namespace std;

typedef struct {
    UINT32              mapNo;
    COOR_2D_POSE_STRU stZeroPoseByCombMap;
} SUB_MAP_COMB_INFO_STRU;

/**************************************************************************************
功能描述: 组合地图文件信息
修改记录:
**************************************************************************************/
class COMB_MAP_FILE_C
{
public:
    COMB_MAP_FILE_C(void)
    {
        MAP_FILE_MNG_C objMapFileMng;
        objMapFileMng.GetCombMapFilePath(strFilePath_);
    }
    
    COMB_MAP_FILE_C(const string &strMapDir)
    {
        MAP_FILE_MNG_C objMapFileMng(strMapDir);
        objMapFileMng.GetCombMapFilePath(strFilePath_);
    }
    
    int Read(list<SUB_MAP_COMB_INFO_STRU> &lstSubMap);
    int Write(list<SUB_MAP_COMB_INFO_STRU> &lstSubMap);
    
private:
    string strFilePath_;
};

/**************************************************************************************
功能描述: 子地图信息
          注意原点和零点的区别，原点指地图左下角的，零点指地图坐标系x y都为0的点
修改记录:
**************************************************************************************/
class SUB_MAP_C
{
public:
    SUB_MAP_C(UINT32 mapNo, IMAGE_COORDINATE_STRU &stMapSize, COORDINATE_2D_STRU &stOriginPosBySubMap, COOR_2D_POSE_STRU &stZeroPoseByCombMap);

    UINT32  GetMapNo(void);
    void    GetOriginPoseByCombMap(COOR_2D_POSE_STRU &stOriginPoseByCombMap);
    void    GetInfo(UINT32 &mapNo, COOR_2D_POSE_STRU &stZeroPoseByCombMap);

    void  TransSubToCombMapPose(COOR_2D_POSE_STRU &stSubMapPose, COOR_2D_POSE_STRU &stCombMapPose);
    void  TransCombToSubMapPose(COOR_2D_POSE_STRU &stCombMapPose, COOR_2D_POSE_STRU &stSubMapPose);
    
    bool  IsPointInMap(const COORDINATE_2D_STRU &stPosByCombMap);
    float GetMinDistSquToMapEdge(const COORDINATE_2D_STRU &stPosByCombMap);
    float GetDistSquToMapEdgeAlongMoveDir(const COOR_2D_POSE_STRU &stCurCarPose);

private:
    UINT32 no_;                                           /* 地图编号，在组合地图中唯一标识一个子地图 */
    IMAGE_COORDINATE_STRU stMapSize_;                   /* 子地图大小 */
    COORDINATE_2D_STRU    stOriginPosBySubMap_;         /* 原点(非零坐标点)坐标 */
    COOR_2D_POSE_STRU     stZeroPoseByCombMap_;         /* 子地图坐标零点在组合地图中的姿态 */
    
    COOR_TF_C        objCombToSubMapTf_;                /* 组合地图与子地图坐标转换 */
    CONVEX_POLYGON_C objSubMapAreaByCombMap_;           /* 子地图在组合地图中的区域 */

    void GetMapAreaByCombMap(CONVEX_POLYGON_C &objArea);
};

/**************************************************************************************
功能描述: 组合地图信息
          主要用于管理多个子地图的关系
修改记录:
**************************************************************************************/
class COMB_MAP_C
{
public:
    COMB_MAP_C(void)
    {
        minValidSubMapNo_  = 0;
        pobjWorkingSubMap_ = NULL;
    }

    COMB_MAP_C(const string &strMapDir) : objMapFileMng_(strMapDir), objCombMapFile_(strMapDir)
    {
        minValidSubMapNo_  = 0;
        pobjWorkingSubMap_ = NULL;
    }
    
    virtual ~COMB_MAP_C(void)
    {
        Clear();
    }

    INT32 Init(void);

    int  CreateSubMap(COOR_2D_POSE_STRU &stSubMapZeroPoseByCombMap, string &strSubMapName);

    bool IsChangeSubMap(const COOR_2D_POSE_STRU &stCurCarPose, string &strSubMapName, COOR_2D_POSE_STRU &stNewMapSetPose);
    int  ChangeSubMap(string &strSubMapName);
    
    int  TransSubToCombMapPose(COOR_2D_POSE_STRU &stSubMapPose, COOR_2D_POSE_STRU &stCombMapPose);
    int  TransCombToSubMapPose(COOR_2D_POSE_STRU &stCombMapPose, COOR_2D_POSE_STRU &stSubMapPose);

    void GetSubMapName(UINT32 subMapNo, string &strFileName);
    void GetSubMapList(list<UINT32> &lstSubMapNo);

    int  GetWorkSubMapNo(void);
    
private:
    MAP_FILE_MNG_C    objMapFileMng_;
    COMB_MAP_FILE_C   objCombMapFile_;
    UINT32            minValidSubMapNo_;                    /* 可分配的子地图号最小值 */
    SUB_MAP_C        *pobjWorkingSubMap_;
    list<SUB_MAP_C *> lstSubMap_;
    
    int  AddSubMap(UINT32 mapNo, IMAGE_COORDINATE_STRU &stMapSize, COORDINATE_2D_STRU &stOriginPos, COOR_2D_POSE_STRU &stZeroPoseByCombMap);
    void Clear(void);
    int  ChangeSubMapByNo(UINT32 subMapNo);

    SUB_MAP_C *SearchSubMap(UINT32 subMapNo);
    SUB_MAP_C *MatchSubMapByUsingMinDist(const COOR_2D_POSE_STRU &stCombMapPose, int exceptSubMapNo);
    SUB_MAP_C *MatchSubMapByUsingMoveDirDist(COOR_2D_POSE_STRU &stCombMapPose, int exceptSubMapNo, float &distSquToEdge);

    int  LoadFromFile(void);
    void SaveToFile(void);
};

/**************************************************************************************
功能描述: 组合地图编辑
修改记录:
**************************************************************************************/
typedef struct {
    UINT32 subMapNo;
    COORDINATE_2D_STRU stLeftButtomPointBySubMap;
    COORDINATE_2D_STRU stRightTopPointBySubMap;
    COORDINATE_2D_STRU stLeftButtomPoint;
    COORDINATE_2D_STRU stRightTopPoint;
} SUB_MAP_AREA_STRU;

typedef struct {
    UINT32 subMapNo;
    IMAGE_COORDINATE_STRU stPictureLeftTopCoord;
    IMAGE_COORDINATE_STRU stImageSize;
} SPLIT_SUB_MAP_INFO_STRU;

class COMB_MAP_EDIT_C
{
public:
    COMB_MAP_EDIT_C(void)
    {
        (void)objCombMap_.Init();
    }
    
    int  MergeSubMaps(list<UINT32> &lstSubMapNo, string &strMergedMapName);
    int  MergeSubMaps(UINT32 aSubMapNo[], int subMapNum, string &strMergedMapName);
    int  MergeAllSubMaps(string &strMergedMapName);
    int  MergeAllSubMapsExceptLast(string &strMergedMapName);

    int  SplitSubMap(GRAY_MAP_C &objMergedMap, SPLIT_SUB_MAP_INFO_STRU &stSplitSubMap);
    int  SplitSubMaps(const string &strSrcMapName, list<SPLIT_SUB_MAP_INFO_STRU> &lstSplitSubMap);
    int  SplitSubMaps(const string &strSrcMapName);
    
private:
    MAP_FILE_MNG_C objMapFileMng_;
    COMB_MAP_C     objCombMap_;

    int GetSubMapEffectArea(UINT32 subMapNo, SUB_MAP_AREA_STRU &stSubMapEffectArea);
    int GetSubMapsEffectArea(list<UINT32> lstSubMapNo, list<SUB_MAP_AREA_STRU> &lstSubMapEffectArea);
    int GetMergedMapArea(list<SUB_MAP_AREA_STRU> &lstSubMapArea, COORDINATE_2D_STRU &stLeftButtomPoint, COORDINATE_2D_STRU &stRightTopPoint);
    
    int MergeSubMapArea(SUB_MAP_AREA_STRU &stSubMapEffectArea, GRAY_MAP_C &objMergedMap);
    int MergeSubMapsArea(list<SUB_MAP_AREA_STRU> &lstSubMapEffectArea, GRAY_MAP_C &objMergedMap);

    int GetSplitSubMaps(const string &strSrcMapName, list<SPLIT_SUB_MAP_INFO_STRU> &lstSplitSubMap);
};

#endif

